# -*- coding: utf-8 -*-
# @author : wanglei
# @date : 2020/4/12 10:20 PM
# @description : 自定义场景，用于继承
from manimlib.imports import *
import math

"""
logo背景场景
"""
class LogoScene(Scene):
    CONFIG = {
        'logo_file':'',
        'introduce':'树先生'
    }

    def setup(self):
       # 勾股树
       level_list = self.getPythagoreanTriple(0.8,4)
       # 填充颜色
       # colors = color_gradient([RED, GREEN, BLUE], len(level_list))
       colors = ['#ff2d51', '#009999', '#00CC00']
       text_colors = ['#009999', '#00CC00', '#ff2d51']
       i = -1
       for square_list in level_list:
           for square in square_list:
               i += 1
               if i < 3:
                   polygon = Polygon(*square)
                   # 将文字设置到方块中
                   intro_text = Text(self.introduce[i], font='smmyingbi')
                   intro_text.scale(0.7)
                   intro_text.move_to(polygon.get_center())
                   polygon.set_stroke(width=0)
                   polygon.set_fill(colors[i], opacity=1)
                   self.play(Write(polygon), Write(intro_text), run_time=0.5)
       self.wait()
    def getPythagoreanTriple(self, init_length, num):
        '''
        获取num组勾股树，每次随机角度
        :return:
        '''
        level_list = []
        for n in range(1, num):
            square_list = []
            if n == 1:
                # 第一个正方形四个顶点
                lu = np.array([-init_length / 2, init_length / 2, 0])
                ru = np.array([init_length / 2, init_length / 2, 0])
                rd = np.array([init_length / 2, -init_length / 2, 0])
                ld = np.array([-init_length / 2, -init_length / 2, 0])
                square_list.append((ld, rd, ru, lu))
                level_list.append(square_list)
            else: # n > 1
                square_list = self.getSquares(level_list[-1])
                level_list.append(square_list)

        return level_list

    def getSquares(self, square_list):
        '''
        根据父节点，生出子节点
        :param square_list:
        :return:
        '''
        child_square_list = []
        for square in square_list:
            x1, y1 = square[0][:-1] # ld 左下
            x2, y2 = square[1][:-1] # rd 右下
            x3, y3 = square[2][:-1] # ru 右上
            x4, y4 = square[3][:-1] # lu 左上
            len = self.getLength(x1, y1, x2, y2)  # 用来得到两点之间的距离
            angle = self.getAngle(x1, y1, x2, y2) # 弧度

            # 获取随机角度
            random_angle = PI/4.5 #self.getRandomDegree()

            # 角度转弧度
            # (temp_x, temp_y) 三个square中间三角形的上顶点
            temp_x = x4 + math.cos(angle + random_angle) * math.cos(math.radians(random_angle)) * len
            temp_y = y4 + math.sin(angle + random_angle) * math.cos(math.radians(random_angle)) * len

            left_square = self.getPointCoordinate(x4, y4, temp_x, temp_y)
            right_square = self.getPointCoordinate(temp_x, temp_y, x3, y3)
            child_square_list.append(left_square)
            child_square_list.append(right_square)
        return child_square_list

    def getPointCoordinate(self, x1, y1, x2, y2):
        '''
        根据两个点获取其余两个点坐标
        :param x1:
        :param y1:
        :param x2:
        :param y2:
        :return:
        '''
        len = self.getLength(x1, y1, x2, y2)  # 用来得到两点之间的距离
        angle = self.getAngle(x1, y1, x2, y2)
        x3 = x1 + math.cos(angle + PI/4) * math.sqrt(2) * len
        y3 = y1 + math.sin(angle + PI/4) * math.sqrt(2) * len
        x4 = x1 + math.cos(angle + PI/2) * len
        y4 = y1 + math.sin(angle + PI/2) * len
        return (np.array([x1,y1,0]), np.array([x2,y2,0]), np.array([x3,y3,0]), np.array([x4,y4,0]))

    def getLength(self, x1, y1, x2, y2):
        '''
        获取两点间长度
        :param x1:
        :param y1:
        :param x2:
        :param y2:
        :return:
        '''
        return math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2))

    def getAngle(self, x1, y1, x2, y2):
        angle = 0.0
        if x1 == x2: # 说明两点在同一条竖直线上
            if y1 > y2:
                angle = PI*3/2
            elif y2 > y1:
                angle = PI/2
        else: # 说明两点不在同一条竖直线上
            temp_angle = math.atan((y2 - y1)/(x2 - x1))
            if x2 > x1: # 说明x2在x0点的左边
                angle = temp_angle
            elif x2 < x1 : # 说明x2在x0的右边
                angle = temp_angle + PI

        return angle

    def getRandomDegree(self):
        # 随机角度
        jiao1 = [10, 70, 30, 50, 40, 45, 35, 65, 15, 85]
        # jiao2 = [80, 20, 60, 40, 50, 45, 55, 25, 75, 5]
        # index = int(random.random() * 10)
        # return jiao1[index], jiao2[index]
        return random.choice(jiao1)

class LogoScene2(Scene):
    CONFIG = {
        'logo_file':'glede.svg',
        'introduce':'鹰视界',
        'main_title':'',
        'sub_title':''
    }
    def setup(self):
        # logo
        logo_min = SVGMobject(self.logo_file).set_fill(BLACK).set_stroke(color=WHITE, width=1)
        introduce_min = TextMobject(
            self.introduce
        )
        logo_min.move_to(UP)
        introduce_min.move_to(0.7 * DOWN)
        logo_intro_min = Group(logo_min, introduce_min)
        logo_intro_min.scale(0.3)
        logo_intro_min.to_edge(UL, buff=0.2)
        self.add(logo_intro_min)

        if self.main_title!='': # 如果有主标题和子标题时，执行
            # 标题和子标题
            title = TextMobject(
                self.main_title
            )
            title.move_to(3*LEFT + 3*UP)
            self.add(title)
            symbol = Circle(radius=0.35, color=BLUE, stroke_width=3, fill_color=WHITE,
                            fill_opacity=0.3)
            catalog = TextMobject(self.sub_title)
            catalog.next_to(symbol)
            sc = Group(symbol, catalog)
            sc.move_to(3*LEFT + 2*UP)
            gp = Group(title, sc)
            gp.scale(0.3)
            gp.move_to(3.4*UP + 5.3*LEFT)
            self.add(gp)

"""
标题目录场景
"""
class TitleAndCatalogScene(LogoScene):
    CONFIG = {
        'embellish':'',
        'title':'',
        'catalogs':[]
    }
    def setup(self):
        super().setup()
        # 标题
        title = TextMobject(
            self.embellish+'：'+self.title,
            tex_to_color_map={self.title: RED}
        )
        title.move_to(3*UP)
        self.add(title)
        self.play(Write(title))
        # 目录
        for i, cl in enumerate(self.catalogs):
            symbol = Circle(radius=0.35, color=BLUE, stroke_width=3, fill_color=WHITE,
                            fill_opacity=0.3)
            catalog = TextMobject(cl)
            catalog.next_to(symbol)
            sc = Group(symbol, catalog)
            sc.scale(0.6)
            sc.move_to(2*LEFT + 1.5*UP-i*UP,aligned_edge=LEFT)
            self.add(sc)
            self.play(FadeIn(sc))
        # 收缩到左上角, 其余子标题移除
        main_sub_title = Group(self.get_mobjects()[1], self.get_mobjects()[2])

        # 标题和子标题
        title = TextMobject(
            self.embellish + '：' + self.title
        )
        title.move_to(3 * LEFT + 3 * UP)
        symbol = Circle(radius=0.35, color=BLUE, stroke_width=3, fill_color=WHITE,
                        fill_opacity=0.3)
        catalog = TextMobject(self.catalogs[0])
        catalog.next_to(symbol)
        sc = Group(symbol, catalog)
        sc.move_to(3 * LEFT + 2 * UP)
        gp = Group(title, sc)
        gp.scale(0.3)
        gp.move_to(3.4 * UP + 5.3 * LEFT)
        for m in list(reversed(self.get_mobjects()))[:-3]:
            self.play(FadeOutAndShiftDown(m))
        self.play(Transform(main_sub_title, gp))

"""
标题
"""
class TitleScene(Scene):
    CONFIG = {
        'title':''
    }
    def setup(self):
        super().setup()
        # 标题
        title = Text(self.title, color = BLACK,font = 'PingFangSC-Regular')
        title.scale(0.5)
        self.play(FadeInFromDown(title, direction= 3* DOWN))